package com.ovopark.organize.server.oss;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Component
@Slf4j
public class StorageUploader {
//    private static Logger log = LoggerFactory.getLogger(StorageUploader.class);
    // 上传地址
    private static String fileUploadAddress;

    @Value("${fileUploadAddress}")
    public void setFileUploadAddress(String fileUploadAddress) {
        this.fileUploadAddress = fileUploadAddress;
    }

    public static InputStream download(String fullUrl) {
        InputStream is = null;
        try {
            CloseableHttpClient httpclient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet(fullUrl);// 使用get方式下载
            HttpResponse response = httpclient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();
        } catch (Exception e) {
            log.error("download", e);
        }
        return is;
    }

    public static OssResult upload(File file, StorageType type, StorageModule storageModule) {
        OssResult ossResult = null;
        Map<String, String> extraHeaders = new HashMap<>();
        extraHeaders.put("storageType", type.name());
        extraHeaders.put("moduleId", String.valueOf(storageModule.getIndex()));

        try {
            String result = uploadToStorage(fileUploadAddress + "api/dc/storage/oss/upload", extraHeaders, file, null);
            log.info("upload result：" + result);
            // 解析返回值，获取真实url
            JSONObject obj = JSONObject.parseObject(result);
            int code = obj.getInteger("code");
            // 成功
            if (code == 0) {
                JSONObject ossObject = obj.getJSONObject("data");
                ossResult = ossObject.toJavaObject(OssResult.class);
            } else {
                // 失败，打印message
                log.info("uploadFileToStorage:" + obj.getString("result"));
            }
        } catch (Exception e) {
            log.error("upload", e);
        }
        return ossResult;
    }


    public static OssResult uploadNewFile(File file,String path,String customFileName) {
        OssResult ossResult = null;
        Map<String, String> param = new HashMap<>();
        param.put("businessCode", "ovopark-basic-platform");
        param.put("enterprisePath", path);
        param.put("customFileName", customFileName);

        try {
            String result = uploadToStorageNew(fileUploadAddress + "api/dc/storage/standard/upload", param, file, null);
            log.info("upload result：" + result);
            // 解析返回值，获取真实url
            JSONObject obj = JSONObject.parseObject(result);
            int code = obj.getInteger("code");
            // 成功
            if (code == 0) {
                JSONObject ossObject = obj.getJSONObject("data");
                ossResult = ossObject.toJavaObject(OssResult.class);
            } else {
                // 失败，打印message
                log.info("uploadFileToStorage:" + obj.getString("result"));
            }
        } catch (Exception e) {
            log.error("upload", e);
        }
        return ossResult;
    }

    private static String uploadToStorageNew(String url, Map<String, String> param, File file, Integer timeOut) throws Exception {
        if (timeOut == null){
            timeOut = 10000;
        }
        RequestConfig requestConfig =  RequestConfig.custom().setSocketTimeout(timeOut).setConnectTimeout(timeOut).build();
        CloseableHttpClient httpclient = HttpClients.createDefault();

        HttpPost httpPost = new HttpPost(url);// 创建httpPost
        httpPost.setConfig(requestConfig);
       /* httpPost.setHeader("Content-Type", "multipart/form-data"); 有这行 会找不到           */

        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
        multipartEntityBuilder.addBinaryBody("file", file);
        if (param != null) {
            Iterator<Map.Entry<String, String>> entries = param.entrySet().iterator();
            while(entries.hasNext()){
                Map.Entry<String, String> entry = entries.next();
                 multipartEntityBuilder.addTextBody(entry.getKey(),entry.getValue());
            }
        }

        HttpEntity httpEntity = multipartEntityBuilder.build();
        httpPost.setEntity(httpEntity);



        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httpPost);
            int state = response.getStatusLine().getStatusCode();
            if (state == HttpStatus.SC_OK) {
                HttpEntity responseEntity = response.getEntity();
                String result = EntityUtils.toString(responseEntity, "UTF-8");
                log.info("request url:" + url + "; response:" + result);
                return result;
            } else {
                log.error("请求返回:" + state + "(" + url + ")");
            }
        } catch(Exception e) {
            log.error("uploadToStorage", e);
        }  finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static void deleteFile(StorageType type, String filePath, StorageModule storageModule) {
        Map<String, String> extraHeaders = new HashMap<>();
        extraHeaders.put("storageType", type.name());
     /* extraHeaders.put("moduleId", String.valueOf(storageModule.getIndex()));
        extraHeaders.put("isDate", "true");*/
        String result = null;
        try {
            result = deleteFromStorage(fileUploadAddress + "/api/dc/storage/oss/delete", extraHeaders, filePath, null);
            // 解析返回值，获取真实url
            JSONObject obj = JSONObject.parseObject(result);

            int code = obj.getInteger("code");
            // 成功
            if (code == 0) {
                log.info("deleteFileSuccess:" + filePath);
            } else {
                // 失败，打印message
                log.info("deleteFileFailed:" + filePath + "; result:" + obj.getString("result"));
            }
        } catch (Exception e) {
            log.error("deleteFile", e);
        }
    }

    private static String uploadToStorage(String url, Map<String, String> extraHeaders, File file, Integer timeOut) throws Exception {
        if (timeOut == null){
            timeOut = 10000;
        }
        RequestConfig requestConfig =  RequestConfig.custom().setSocketTimeout(timeOut).setConnectTimeout(timeOut).build();

        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);// 创建httpPost
        httpPost.setConfig(requestConfig);
//        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        if (extraHeaders != null) {
            Iterator<Map.Entry<String, String>> entries = extraHeaders.entrySet().iterator();
            while(entries.hasNext()){
                Map.Entry<String, String> entry = entries.next();
                httpPost.setHeader(entry.getKey(), entry.getValue());
            }
        }
        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
        multipartEntityBuilder.addBinaryBody("file", file);
        HttpEntity httpEntity = multipartEntityBuilder.build();
        httpPost.setEntity(httpEntity);

        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httpPost);
            int state = response.getStatusLine().getStatusCode();
            if (state == HttpStatus.SC_OK) {
                HttpEntity responseEntity = response.getEntity();
                String result = EntityUtils.toString(responseEntity, "UTF-8");
                log.info("request url:" + url + "; response:" + result);
                return result;
            } else {
                log.error("请求返回:" + state + "(" + url + ")");
            }
        } catch(Exception e) {
            log.error("uploadToStorage", e);
        }  finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    private static String deleteFromStorage(String url, Map<String, String> extraHeaders, String filePath, Integer timeOut) throws Exception {
        if (timeOut == null){
            timeOut = 10000;
        }
        RequestConfig requestConfig =  RequestConfig.custom().setSocketTimeout(timeOut).setConnectTimeout(timeOut).build();

        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);// 创建httpPost
        httpPost.setConfig(requestConfig);
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        if (extraHeaders != null) {
            Iterator<Map.Entry<String, String>> entries = extraHeaders.entrySet().iterator();
            while(entries.hasNext()){
                Map.Entry<String, String> entry = entries.next();
                httpPost.setHeader(entry.getKey(), entry.getValue());
            }
        }
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("filePath", filePath));

        httpPost.setEntity(new UrlEncodedFormEntity(params));
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httpPost);
            int state = response.getStatusLine().getStatusCode();
            if (state == HttpStatus.SC_OK) {
                HttpEntity responseEntity = response.getEntity();
                String result = EntityUtils.toString(responseEntity, "UTF-8");
                log.info("request url:" + url + "; response:" + result);
                return result;
            } else {
                log.error("请求返回:" + state + "(" + url + ")");
            }
        } catch(Exception e) {
            log.error("deleteFromStorage", e);
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
